package com.alogic.matcher.impl;

import com.alogic.matcher.CommonMatcher;
import com.anysoft.util.Properties;

import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * ip段的匹配
 *
 * @since 1.6.12.57 [20200103]
 */
public class IpSegment implements CommonMatcher {
    protected static final Pattern ip = Pattern.compile("^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$");
    protected static final Pattern ipSegment = Pattern.compile("^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\/(\\d{1,2})$");
    protected TreeMap<Long,Long> segments = new TreeMap<Long,Long>();
    public IpSegment(String pattern, Properties p){
        String[] data = pattern.split(",");
        for (String segment:data){
            Matcher m = ipSegment.matcher(segment);
            if (m.find()){
                Long baseIp = (getLong(m.group(1),0) << 24) +
                        (getLong(m.group(2),0) << 16) +
                        (getLong(m.group(3),0) << 8) +
                        getLong(m.group(4),0);
                Long mask = getLong(m.group(5),0);
                segments.put(baseIp,mask);
            }
        }
    }

    @Override
    public boolean isMatch(String data) {
        Matcher m = ip.matcher(data);
        if (m.find()){
            Long ipLong = (getLong(m.group(1),0) << 24) +
                    (getLong(m.group(2),0) << 16) +
                    (getLong(m.group(3),0) << 8) +
                    getLong(m.group(4),0);
            Map.Entry<Long,Long> found = segments.floorEntry(ipLong);
            if (found != null){
                int mask = 0xffffffff << (32 - found.getValue());
                return ((ipLong ^ found.getKey())&mask) == 0;
            }
        }
        return false;
    }

    public long getLong(String value,long dft){
        try{
            return Long.parseLong(value);
        }catch (Exception ex){
            return dft;
        }
    }
}
